#pragma once
#include <iostream>

#include <cerrno>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "Log.hpp"
#include "sockaddr.hpp"
#include "Comm.hpp"

#define DEFAULT_SOCKFD -1
#define BUFFERSIZE 1024
#define RECONNECT_SIZE 5

int reconnect_size = 1;

class Client
{
public:
    Client(std::string ip, in_port_t port)
        : _sockfd(DEFAULT_SOCKFD), _sk(ip, port)
    {
    }
    ~Client()
    {
    }
    void Init()
    {
        // 创建套接字
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        CheckRet(_sockfd, client_name, func_types[0]); // 保证成功才调用，只是打印成功的信息

        // 请求连接
        int ret_connect = connect(_sockfd, (const sockaddr *)(&_sk.addr_in()), _sk.len());
        CheckRet(ret_connect, client_name, func_types[6]);

        // 重连成功
        reconnect_size = 1;
    }
    void Start()
    {
        std::string fun = Choose_Function();
        //使用对应功能
        std::cout << "[" << fun << "]# ";
        std::string write_buffer;
        std::getline(std::cin, write_buffer);
        // 发送信息
        int ret_write = write(_sockfd, write_buffer.c_str(), write_buffer.size());
        CheckRet(ret_write, client_name, func_types[5]);

        // 接收server的响应
        char read_buffer[BUFFERSIZE];
        int ret_read = read(_sockfd, read_buffer, sizeof(read_buffer) - 1);
        CheckRet(ret_read, client_name, func_types[4]);

        read_buffer[ret_read] = 0;
        std::cout << read_buffer << std::endl;

        close(_sockfd);
    }

private:
    int _sockfd;
    Sockaddr _sk;

    std::string Choose_Function()
    {
        char read_buffer[BUFFERSIZE];

        //接收到功能选择的信息
        int ret_read = read(_sockfd, read_buffer, sizeof(read_buffer) - 1);
        CheckRet(ret_read, client_name, func_types[4]);
        read_buffer[ret_read] = 0;
        std::cout << read_buffer << std::endl;
        //选择功能
        std::string write_buffer;
        std::cout << "选择功能# ";
        std::getline(std::cin, write_buffer);
        // 发送信息
        int ret_write = write(_sockfd, write_buffer.c_str(), write_buffer.size());
        CheckRet(ret_write, client_name, func_types[5]);

        return write_buffer;
    }
};